package com.sun.redis.controller;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;

import java.util.Collections;
import java.util.UUID;

/**
 * SpringBoot整合Jedis实现
 */
@RestController
@RequestMapping("/jedis")
public class JedisController {

    @Autowired
    private Jedis jedis;

    private static final String LOCK_SUCCESS = "OK";
    private static final Long RELEASE_SUCCESS = 1L;

    // http://localhost:8080/jedis/set/test
    @GetMapping(value = "/set/{key}")
    public String set(@PathVariable String key) {
        jedis.set(key, "set-value-" + key);
        return "set success";
    }

    // http://localhost:8080/jedis/get/test
    @GetMapping(value = "/get/{key}")
    public String get(@PathVariable String key) {
        return jedis.get(key);
    }

    // http://localhost:8080/jedis/del/test
    @GetMapping(value = "/del/{key}")
    public String del(@PathVariable String key) {
        jedis.del(key);
        return "delete success";
    }

    // http://localhost:8080/jedis/lock/test
    @GetMapping(value = "/lock/{key}")
    public String lock(@PathVariable String key) {
        boolean lockFlag = lock(jedis, key, UUID.randomUUID().toString(), 30000);// 30s
        if(lockFlag) {
            return "正在执行，获取值为：" + get(key);
        } else {
            return "已上锁，无法重复执行";
        }
    }

    // http://localhost:8080/jedis/unlock/test
    @GetMapping(value = "/unlock/{key}")
    public String unLock(@PathVariable String key) {
        boolean lockFlag = unLock(jedis, key, get(key));
        if(lockFlag) {
            return "解锁成功";
        } else {
            return "没有需要解锁的数据";
        }
    }

    public static boolean lock(Jedis jedis, String lockKey, String requestId, long millisecondsToExpire) {
        String result = jedis.set(lockKey, requestId, SetParams.setParams().nx().px(millisecondsToExpire));
        if (LOCK_SUCCESS.equals(result)) {
            return true;
        }
        return false;
    }

    public static boolean unLock(Jedis jedis, String lockKey, String requestId) {
        if(StringUtils.isNotBlank(requestId)) {
            // lua脚本
            String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
            Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
            if (RELEASE_SUCCESS.equals(result)) {
                return true;
            }
        }
        return false;
    }

}
